Linux cgroup CPU Limit
1st:lkinoue.icon
2nd: kimitoboku.icon
そもそもControl Groups(cgroups)とは?
プロセス単位でリソースの制御ができるLinuxの機能
cgroups v1 and v2
subsystemという形で各リソースに関する設定が存在
cpu, mem, blkio(ブロックデバイス), etc...
設定に使用するcgroupsという特殊なfilesystemが/sys/fs以下にマウントされている(ことが多い)
e.g.) cpu: /sys/fs/cgroup
cgroups v1
cgroups v2
cfs_quota_usを手がかりにたどる
code:c
{
.name = "cfs_quota_us",
.read_s64 = cpu_cfs_quota_read_s64,
.write_s64 = cpu_cfs_quota_write_s64,
},
code:c
static int tg_set_cfs_quota(struct task_group *tg, long cfs_quota_us)
{
u64 quota, period, burst;
period = ktime_to_ns(tg->cfs_bandwidth.period);
burst = tg->cfs_bandwidth.burst;
if (cfs_quota_us < 0)
quota = RUNTIME_INF;
else if ((u64)cfs_quota_us <= U64_MAX / NSEC_PER_USEC)
quota = (u64)cfs_quota_us * NSEC_PER_USEC;
else
return -EINVAL;
return tg_set_cfs_bandwidth(tg, period, quota, burst);
}
code:c
static int tg_set_cfs_bandwidth(struct task_group *tg, u64 period, u64 quota, u64 burst)
{
...
ret = __cfs_schedulable(tg, period, quota);
if (ret)
goto out_unlock;
...
}
code:c
static int __cfs_schedulable(struct task_group *tg, u64 period, u64 quota)
{
...
ret = walk_tg_tree(tg_cfs_schedulable_down, tg_nop, &data);
}
code:c
static int tg_cfs_schedulable_down(struct task_group *tg, void *data)
{
struct cfs_schedulable_data *d = data;
struct cfs_bandwidth *cfs_b = &tg->cfs_bandwidth;
s64 quota = 0, parent_quota = -1;
if (!tg->parent) {
quota = RUNTIME_INF;
} else {
struct cfs_bandwidth *parent_b = &tg->parent->cfs_bandwidth;
quota = normalize_cfs_quota(tg, d);
parent_quota = parent_b->hierarchical_quota;
/*
* Ensure max(child_quota) <= parent_quota. On cgroup2,
* always take the min. On cgroup1, only inherit when no
* limit is set:
*/
if (cgroup_subsys_on_dfl(cpu_cgrp_subsys)) {
quota = min(quota, parent_quota);
} else {
if (quota == RUNTIME_INF)
quota = parent_quota;
else if (parent_quota != RUNTIME_INF && quota > parent_quota)
return -EINVAL;
}
}
cfs_b->hierarchical_quota = quota;
return 0;
}
this is set as function ptr for sheduling class
Pick up the highest-prio task
calll per scheduling class implementation
code:c
static int cpu_cfs_stat_show(struct seq_file *sf, void *v)
{
...
}
hrtimer period_timer
comment
cpu.cfs_quota_us を制限すると、idleが増える
https://iret.media/wp-content/uploads/2015/01/20150116_cgroup_005-2-1024x573.png
cgroup v1では、どの階層にもタスクを登録できる
https://gihyo.jp/assets/images/admin/serial/01/linux_containers/0037/thumb/TH800_001.png
code:c
static int tg_set_cfs_bandwidth(struct task_group *tg, u64 period, u64 quota, u64 burst)
nr is abbrev of number